package com.freewater.springboot.demo.aop.api.pointcut;

import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;

public class PointCuts {

    public static void main(String[] args) {
        PointCuts pointCuts = new PointCuts();
        pointCuts.testNameMatchMethodPointcut();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>");
        pointCuts.testJdkRegexPointCut();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>");
        pointCuts.testDynamicMethod();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>");
        pointCuts.testAspectExpressionPointcut();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>");
        pointCuts.testAnnotationPointcut();
    }

    public void testNameMatchMethodPointcut() {
        NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
        // 匹配add方法
        pointcut.addMethodName("add");
        // 匹配sub方法
        pointcut.addMethodName("sub");
        // 使用默认的advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new SimpleBeforeAdvice());
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(advisor);
        proxyFactory.setTarget(new CalculatorImpl());
        Calculator proxy = (Calculator) proxyFactory.getProxy();
        int add = proxy.add(1, 5);
        System.out.printf("加法计算值: %s%n", add);
        double divide = proxy.divide(10, 10);
        System.out.printf("除法计算值: %s%n", divide);
    }

    public void testJdkRegexPointCut() {
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        // 设置匹配所以以get开头的方法
        pointcut.setPattern(".*get");
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new SimpleBeforeAdvice());
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(advisor);
        proxyFactory.setTarget(new CalculatorImpl());
        Calculator proxy = (Calculator) proxyFactory.getProxy();
        int add = proxy.add(1, 5);
        System.out.printf("加法计算值: %s%n", add);
        double divide = proxy.divide(10, 10);
        System.out.printf("除法计算值: %s%n", divide);
    }

    public void testDynamicMethod() {
        SimpleDynamicMethodPointcut pointcut = new SimpleDynamicMethodPointcut();
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new SimpleBeforeAdvice());
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(advisor);
        proxyFactory.setTarget(new CalculatorImpl());
        Calculator proxy = (Calculator) proxyFactory.getProxy();
        System.out.println();
        int add = proxy.add(15, 5);
        System.out.printf("加法计算值: %s%n", add);
        add = proxy.add(55, 5);
        System.out.printf("加法计算值: %s%n", add);
    }

    public void testAspectExpressionPointcut() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(* *..aop.api.pointcut..*(..))");
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new SimpleBeforeAdvice());
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(advisor);
        proxyFactory.setTarget(new CalculatorImpl());
        Calculator proxy = (Calculator) proxyFactory.getProxy();
        System.out.println();
        int add = proxy.add(5, 5);
        System.out.printf("加法计算值: %s%n", add);
    }

    public void testAnnotationPointcut() {
        AnnotationMatchingPointcut pointcut = AnnotationMatchingPointcut.forMethodAnnotation(AdviceRequired.class);
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new SimpleBeforeAdvice());
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(new CalculatorImpl());
        proxyFactory.addAdvisor(advisor);
        Calculator proxy = (Calculator) proxyFactory.getProxy();
        int sub = proxy.sub(5, 5);
        System.out.printf("减法计算值: %s%n", sub);
        int add = proxy.add(5, 5);
        System.out.printf("加法计算值: %s%n", add);
    }
}
